library chrome;

include <core.vhs>
include <shell.vhs>

import core::*;
import core::Logging::*;
import core::Pattern::*;
import shell::*;

const MAX_VERSION = 19;

const FIRST_REVISION = 3;

/*const versions = [
'1.0.154.65',
'2.0.172.8',
'3.0.195.38',
'4.1.249.1067',
'5.0.396.0',
'6.0.496.0',
'7.0.548.0',
'8.0.561.0',
'9.0.600.0',
'10.0.651.0',
'11.0.699.0',
'12.0.747.0',
'13.0.782.99',
'14.0.836.0',
'15.0.876.0',
'16.0.912.9',
'17.1.963.5',
'18.0.999.0',
'19.0.1085.0'] */

const BASE_LOCATION = '/storage/vhnguyen/chrome/'

const CODEBASES_COUNT = 40;

const CODEBASES = [
'1.0.154.53', 
'1.0.154.65',
'2.0.169.0',
'2.0.172.8',
'3.0.182.2',
'3.0.195.38',
'4.0.212.0',
'4.1.249.1067',
'5.0.306.0',
'5.0.396.0',
'6.0.397.0',
'6.0.496.0',
'7.0.497.0',
'7.0.548.0',
'8.0.549.0',
'8.0.561.0',
'9.0.562.0',
'9.0.600.0',
'10.0.601.0',
'10.0.651.0',
'11.0.652.0',
'11.0.699.0',
'12.0.700.0',
'12.0.747.0',
'13.0.748.0',
'13.0.782.99',
'14.0.783.0',
'14.0.836.0',
'15.0.837.0',
'15.0.876.0',
'16.0.877.0',
'16.0.912.9',
'17.0.913.0',
'17.1.963.5',
'18.0.1000.0',
'18.0.999.0',
'19.0.1028.0',
'19.0.1085.0',
'20.0.1086.0',
'21.0.1141.0'
]

function getSrcLocation(index) BASE_LOCATION + CODEBASES[index] + '/src/'

// Annotate file in FSF (full specified filename) at revision
// Return the FSF of cache file if success, otherwise, return null.
function blameRevision(path, revision=0, showError = true, FSF = locateInCodebase(path), version='') {
	var cmd = format('/usr/bin/svn blame %s %s', if (revision>0) '-r ' + revision else '', FSF);
	var blame_file = 'blame-cache/' + path.replace('/', '_') + 
			(if (revision>0) '.r' + revision else '.v' + version) + '.blame';
	
	var code = if (fileExists(blame_file)) 0 
		else if (fileExists(FSF)) Runtime.exec2(blame_file, ['/bin/sh', '-c', cmd]);
		else -1;  // cannot locate path in any codebase
	if (code == 0)
		return blame_file;
	if (showError) log_error("Error running blame on file %s [rev:%s], error code = %d", FSF, revision, code);
	return null;
}

var version_revision = null;
var versions = null;

function initVersionInformation(revfile = 'ver2rev.csv') {
	println("Loading version to revision table...");
	version_revision = map [];
	versions = list [];
	var ver2revPat = pattern<DataPart>($dataPattern=@'^([^,]*),(\d+)$', $minOccur=0, $maxOccur=999999) {
		//println("Found %s", this[1]);
		var ver = this[1].trim();
		version_revision.put(ver, Runtime.asInt(this[2] + ''));
		versions.add(ver);
	}
	var ip = new SequenceStream(revfile, 4096);
	ver2revPat(input = ip);
	
	println("%d entr(ies) found", version_revision.size());
}

function ver2rev(version) {
	if (version_revision == null)
		initVersionInformation();
	return version_revision.get(version);
}

function getReleasedVersions() {
	if (version_revision == null)
		initVersionInformation();
	return versions; //version_revision.keySet();
}

function locateInCodebase(path) {
	var fullpath = '';
	for (var i = chrome::CODEBASES_COUNT - 1; i >= 0; i--) {
		fullpath = chrome::getSrcLocation(i) + path;
		if (fileExists(fullpath)) return fullpath;
	}
	return null;
}

pattern<DataPart> AnnotatedLine($dataPattern=@'^\s*(\d+)\s([^\s]*)(.+?)$', $minOccur=0) [this[1]+'', this[2], this[3].trim()];